package cmd

import (
	"fmt"
	"gosync/modules"
	"io"
	"log"
	"net"
	"os"

	"github.com/codegangsta/cli"
)

var CmdClient = cli.Command{
	Name:        "client",
	Usage:       "基于TCP/IP协议的文件传输客户端",
	Description: "通用传输组件。完成基于TCP/IP协议的文件传输工作。",
	Action:      runClient,
	Flags: []cli.Flag{
		cli.StringFlag{"host", "127.0.0.1", "server host", ""},   //主机地址
		cli.StringFlag{"port", "8000", "server listen port", ""}, //传输端口
		cli.StringFlag{"file", "", "transfer file", ""},          //传输文件名称
	},
}

func runClient(ctx *cli.Context) {
	syncHost := ctx.String("host")
	listenPort := ctx.String("port")
	syncFile := ctx.String("file")

	if len(syncHost) == 0 {
		log.Fatal("Missing required --host parameter")
	}

	if len(syncFile) == 0 {
		log.Fatal("Missing required --file parameter")
	}

	destination := fmt.Sprintf("%s:%s", syncHost, listenPort)
	clientSend(syncFile, destination)

}

//客户端发送文件
func clientSend(files string, destination string) {
	//获取文件信息
	fInfo := modules.GetFileInfo(files)
	newName := fmt.Sprintf("%s", fInfo.FName)
	// 构造上传指令
	cmdLine := fmt.Sprintf("upload %s %d %d %d %s ", newName, fInfo.FMtime.Unix(),
		fInfo.FPerm, fInfo.FSize, fInfo.FMd5)
	//net.Dial tcp syncHost:listenPort
	cn, err := net.Dial("tcp", destination)
	if err != nil {
		fmt.Println("connect error", err)
		return
	}
	defer cn.Close()
	cn.Write([]byte(cmdLine)) //发送上传指令
	cn.Write([]byte("\r\n"))  //发送结束指令
	fileHandle, err := os.Open(files)
	if err != nil {
		fmt.Println("open ERROR", err)
		return
	}

	//func Copy(dst Writer, src Reader) (written int64, err error)
	//Copy 将 src 复制到 dst，直到在 src 上到达 EOF 或发生错误。
	//它返回复制的字节数，如果有的话，还会返回在复制时遇到的第一个错误。
	io.Copy(cn, fileHandle)
	for {
		//若 dst 实现了 ReaderFrom 接口，其复制操作可通过调用 dst.ReadFrom(src) 实现。
		//此外，若 dst 实现了 WriterTo 接口，其复制操作可通过调用 src.WriteTo(dst) 实现。
		buffer := make([]byte, 1024)
		num, err := cn.Read(buffer)
		if err == nil && num > 0 {
			fmt.Println(string(buffer[:num]))
			break
		}
	}
}
